package cmd

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"github.com/spf13/cobra"
)

// 配置相关命令
var (
	// 配置文件路径
	configPath string

	configCmd = &cobra.Command{
		Use:   "config",
		Short: formatHelp("配置管理", "Configuration management"),
		Long:  `管理 gitlog 的配置信息，包括提交类型、输出格式等。`,
	}
)

// 配置项描述
var configItems = []struct {
	name        string
	description string
	example     string
}{
	{
		"types",
		"需要包含的提交类型，使用逗号分隔。使用空字符串(\"\")表示无类型提交。",
		"feat,feature,\"\"",
	},
	{
		"format",
		"定义提交信息的输出格式模板。支持多种变量和修饰符。",
		"* {title} {(version)} {[scope]}",
	},
	{
		"detail_format",
		"定义详细信息的输出格式模板。支持多种变量和修饰符。",
		"{order}. {detail}",
	},
}

// 格式示例
var formatExamples = []struct {
	format string
	desc   string
	output string
}{
	{
		"* {title} {(version)} {[scope]}",
		"列表格式（默认）| List format (default)",
		"* 添加用户登录功能 (v1.0.0) [user-module]",
	},
	{
		"{type}{(scope)}: {title} {(version)}",
		"标准格式 | Standard format",
		"feature(user-module): 添加用户登录功能 (v1.0.0)",
	},
	{
		"[{type}] {title} {[scope]}",
		"方括号格式 | Square bracket format",
		"[feature] 添加用户登录功能 [user-module]",
	},
	{
		"{original}",
		"原始格式 | Original format",
		"feat(user-module): 添加用户登录功能 v1.0.0",
	},
}

// 详细信息格式示例
var detailFormatExamples = []struct {
	format string
	desc   string
	output string
	cmd    string
}{
	{
		"{order}. {detail}",
		"有序列表（默认）| Ordered list (default)",
		"1. 详细信息内容",
		"gitlog config set --detail_format \"{order}. {detail}\"",
	},
	{
		"- {detail}",
		"无序列表（短横线）| Unordered list with hyphen",
		"- 详细信息内容",
		"gitlog config set --detail_format \"- {detail}\"",
	},
	{
		"* {detail}",
		"无序列表（星号）| Unordered list with asterisk",
		"* 详细信息内容",
		"gitlog config set --detail_format \"* {detail}\"",
	},
	{
		"    {detail}",
		"无头格式 | No prefix format",
		"    详细信息内容",
		"gitlog config set --detail_format \"    {detail}\"",
	},
	{
		"[{order}] {detail}",
		"带方括号的序号 | Numbered with square brackets",
		"[1] 详细信息内容",
		"gitlog config set --detail_format \"[{order}] {detail}\"",
	},
	{
		"({order}) {detail}",
		"带圆括号的序号 | Numbered with parentheses",
		"(1) 详细信息内容",
		"gitlog config set --detail_format \"({order}) {detail}\"",
	},
}

// 获取配置命令
var getConfigCmd = &cobra.Command{
	Use:   "get [config_name]",
	Short: formatHelp("获取配置项的值", "Get configuration value"),
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		config := loadConfig()
		name := args[0]

		switch name {
		case "types":
			fmt.Println(strings.Join(config.IncludeTypes, ","))
		case "format":
			fmt.Println(config.Format)
		case "detail_format":
			fmt.Println(config.DetailFormat)
		default:
			fmt.Printf("未知的配置项: %s\n", name)
		}
	},
}

// 设置配置命令
var setConfigCmd = &cobra.Command{
	Use:   "set",
	Short: formatHelp("设置配置", "Set configuration"),
	Run: func(cmd *cobra.Command, args []string) {
		config := loadConfig()
		updated := false

		if types, err := cmd.Flags().GetStringSlice("types"); err == nil && cmd.Flags().Changed("types") {
			config.IncludeTypes = types
			updated = true
		}

		if format, err := cmd.Flags().GetString("format"); err == nil && cmd.Flags().Changed("format") {
			config.Format = format
			updated = true
		}

		if detailFormat, err := cmd.Flags().GetString("detail_format"); err == nil && cmd.Flags().Changed("detail_format") {
			config.DetailFormat = detailFormat
			updated = true
		}

		if !updated {
			fmt.Println("未指定要更新的配置项")
			return
		}

		if err := saveConfig(config); err != nil {
			fmt.Printf("保存配置失败: %v\n", err)
			return
		}
		fmt.Println("配置已更新 | Configuration updated")
	},
}

// 重置配置命令
var resetConfigCmd = &cobra.Command{
	Use:   "reset",
	Short: formatHelp("重置为默认配置", "Reset to default configuration"),
	Run: func(cmd *cobra.Command, args []string) {
		if err := saveConfig(defaultConfig); err != nil {
			fmt.Printf("重置配置失败: %v\n", err)
			return
		}
		fmt.Println("配置已重置为默认值 | Configuration has been reset to defaults")
	},
}

// 列出配置命令
var listConfigCmd = &cobra.Command{
	Use:   "list",
	Short: formatHelp("列出所有配置项", "List all configuration items"),
	Run: func(cmd *cobra.Command, args []string) {
		config := loadConfig()
		showDesc, _ := cmd.Flags().GetBool("desc")

		if showDesc {
			// 显示 types 配置区域
			fmt.Println("\n[types]")
			fmt.Printf("当前值 | Current Value:\n")
			if len(config.IncludeTypes) == 0 {
				fmt.Printf("\t<empty>\n")
			} else {
				fmt.Printf("\t%s\n", strings.Join(config.IncludeTypes, ","))
			}
			fmt.Printf("描述 | Description:\n")
			fmt.Printf("\t需要包含的提交类型，使用逗号分隔\n")
			fmt.Printf("\tCommit types to include, separated by commas\n")
			fmt.Printf("使用示例 | Usage Examples:\n")
			fmt.Printf("\t包含无类型提交:\n")
			fmt.Printf("\t  gitlog config set --types feat,feature,\"\"\n")
			fmt.Printf("\t不包含无类型提交:\n")
			fmt.Printf("\t  gitlog config set --types feat,feature\n")
			fmt.Printf("说明 | Notes:\n")
			fmt.Printf("\t使用空字符串(\"\")表示无类型提交\n")
			fmt.Printf("\tUse empty string (\"\") to represent commits without type\n")

			// 显示 format 配置区域
			fmt.Println("\n[format]")
			fmt.Printf("当前值 | Current Value:\n")
			fmt.Printf("\t%s\n", config.Format)
			fmt.Printf("描述 | Description:\n")
			fmt.Printf("\t定义提交信息的输出格式模板\n")
			fmt.Printf("\tDefine output format template\n")

			fmt.Printf("\n基础变量 | Basic Variables:\n")
			fmt.Printf("\t%-15s: %s\n\t%-15s  %s\n", "title", "提交标题", " ", "commit title")
			fmt.Printf("\t%-15s: %s\n\t%-15s  %s\n", "scope", "修改范围", " ", "modification scope")
			fmt.Printf("\t%-15s: %s\n\t%-15s  %s\n", "version", "版本号", " ", "version number")
			fmt.Printf("\t%-15s: %s\n\t%-15s  %s\n", "original", "原始提交信息", " ", "original commit message")
			fmt.Printf("\t%-15s: %s\n\t%-15s  %s\n", "type", "提交类型", " ", "commit type")

			fmt.Printf("\n格式示例 | Format Examples:\n")
			for _, e := range formatExamples {
				fmt.Printf("\t格式 | Format:  %s\n", e.format)
				fmt.Printf("\t说明 | Desc:    %s\n", e.desc)
				fmt.Printf("\t示例 | Example: %s\n\n", e.output)
			}

			// 显示 detail_format 配置区域
			fmt.Println("\n[detail_format]")
			fmt.Printf("当前值 | Current Value:\n")
			fmt.Printf("\t%s\n", config.DetailFormat)
			fmt.Printf("描述 | Description:\n")
			fmt.Printf("\t定义详细信息的输出格式模板\n")
			fmt.Printf("\tDefine detail information output format template\n")

			fmt.Printf("\n基础变量 | Basic Variables:\n")
			fmt.Printf("\t%-15s: %s\n\t%-15s  %s\n", "detail", "详细信息内容", " ", "detail content")
			fmt.Printf("\t%-15s: %s\n\t%-15s  %s\n", "order", "序号（从1开始）", " ", "order number (starts from 1)")

			fmt.Printf("\n格式示例 | Format Examples:\n")
			for _, e := range detailFormatExamples {
				fmt.Printf("\t格式 | Format:  %s\n", e.format)
				fmt.Printf("\t说明 | Desc:    %s\n", e.desc)
				fmt.Printf("\t示例 | Example: %s\n", e.output)
				fmt.Printf("\t命令 | Command: %s\n\n", e.cmd)
			}
		} else {
			// 只显示名称和当前值
			fmt.Printf("%-15s\t%s\n", "types", strings.Join(config.IncludeTypes, ","))
			fmt.Printf("%-15s\t%s\n", "format", config.Format)
			fmt.Printf("%-15s\t%s\n", "detail_format", config.DetailFormat)
		}
	},
}

// 初始化配置
func init() {
	// 初始化配置文件路径
	home, err := os.UserHomeDir()
	if err != nil {
		home = "."
	}
	configPath = filepath.Join(home, ".gitlog.json")

	// 添加配置相关命令
	rootCmd.AddCommand(configCmd)
	configCmd.AddCommand(listConfigCmd)
	configCmd.AddCommand(getConfigCmd)
	configCmd.AddCommand(setConfigCmd)
	configCmd.AddCommand(resetConfigCmd)

	// 设置命令行参数
	setConfigCmd.Flags().StringSlice("types", defaultConfig.IncludeTypes, 
		formatHelp("要包含的提交类型（用逗号分隔，使用\"\"表示无类型）", "Commit types to include (comma separated, use \"\" for no type)"))
	setConfigCmd.Flags().String("format", defaultConfig.Format,
		formatHelp("输出格式模板", "Output format template"))
	setConfigCmd.Flags().String("detail_format", defaultConfig.DetailFormat,
		formatHelp("详细信息格式模板", "Detail information output format template"))

	listConfigCmd.Flags().BoolP("desc", "d", false, formatHelp("显示详细描述", "Show detailed description"))
}

// 配置文件操作
func loadConfig() Config {
	data, err := os.ReadFile(configPath)
	if err != nil {
		return defaultConfig
	}

	var config Config
	if err := json.Unmarshal(data, &config); err != nil {
		return defaultConfig
	}
	return config
}

func saveConfig(config Config) error {
	data, err := json.MarshalIndent(config, "", "  ")
	if err != nil {
		return err
	}
	return os.WriteFile(configPath, data, 0644)
} 